﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using iWare.Wms.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;

namespace iWare.Wms.Application
{
    /// <summary>
    /// 所属库区服务
    /// </summary>
    [Route("api/Area")]
    [ApiDescriptionSettings("仓库基础数据", Name = "Area", Order = 100)]

    public class WareAreaService : ControllerBase, IDynamicApiController, ITransient
    {
        private readonly IRepository<WareArea> _wareAreaRep; // 所属库区仓储

        #region 默认
        /// <summary>
        /// 默认
        /// </summary>
        /// <param name="wareAreaRep"></param>
        public WareAreaService(
            IRepository<WareArea> wareAreaRep
        )
        {
            _wareAreaRep = wareAreaRep;
        }
        #endregion

        /// <summary>
        /// 分页查询所属库区
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("page")]
        public async Task<PageResult<WareAreaOutput>> Page([FromQuery] WareAreaInput input)
        {
            var areaList= await _wareAreaRep.DetachedEntities
                .Where(input.AreaType != AreaTypeEnum.ALL, u => u.AreaType == input.AreaType)
                .Where(!string.IsNullOrEmpty(input.AreaCode), u => EF.Functions.Like(u.AreaCode, $"%{input.AreaCode.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.AreaName), u => EF.Functions.Like(u.AreaName, $"%{input.AreaName.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.SearchBeginTime), u => u.CreatedTime >= DateTime.Parse(input.SearchBeginTime.Trim()) &&
                 u.CreatedTime <= DateTime.Parse(input.SearchEndTime.Trim()))
                .OrderBy(PageInputOrder.OrderBuilder<WareAreaInput>(input))
                .ProjectToType<WareAreaOutput>()
                .ToADPagedListAsync(input.PageNo, input.PageSize);

            foreach (var item in areaList.Rows)
            {
                if(item.AreaType == AreaTypeEnum.ZD) item.AreaTypeName = "自动库";
                if (item.AreaType == AreaTypeEnum.NZD) item.AreaTypeName = "非自动库";
                if (item.AreaType == AreaTypeEnum.XN) item.AreaTypeName = "虚拟库";
                if (item.AreaType == AreaTypeEnum.AGV) item.AreaTypeName = "Agv库区";
            }

            return areaList;
        }

        /// <summary>
        /// 获取所属库区列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("list")]
        public async Task<List<WareArea>> GetList()
        {
            return await _wareAreaRep.DetachedEntities.ToListAsync();
        }

        

        /// <summary>
        /// 增加所属库区
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task Add(AddWareAreaInput input)
        {
            var isExist = await _wareAreaRep.DetachedEntities
                .AnyAsync(u => u.AreaName == input.AreaName || u.AreaCode == input.AreaCode);
            if (isExist) throw Oops.Oh(ErrorCode.D5000);

            var wareReservoirArea = input.Adapt<WareArea>();
            await _wareAreaRep.InsertAsync(wareReservoirArea);
        }

        /// <summary>
        /// 删除所属库区
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("delete")]
        public async Task Delete([FromBody] DeleteWareAreaInput input)
        {
            int length = input.Id.Count;
            for (int i = 0; i < length; i++)
            {
                long Id = input.Id[i];
                var wareReservoirArea = await _wareAreaRep.FirstOrDefaultAsync(u => u.Id == Id);
                await _wareAreaRep.DeleteAsync(wareReservoirArea);
            }
        }

        /// <summary>
        /// 更新所属库区
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("edit")]
        public async Task Update(UpdateWareAreaInput input)
        {
            var isExist = await _wareAreaRep.DetachedEntities
                .AnyAsync(u => (u.AreaName == input.AreaName || u.AreaCode == input.AreaCode) && u.Id != input.Id);
            if (isExist) throw Oops.Oh(ErrorCode.D5000);

            var wareReservoirArea = input.Adapt<WareArea>();
            await _wareAreaRep.UpdateAsync(wareReservoirArea, ignoreNullValues: true);
        }
    }
}
